home *** CD-ROM | disk | FTP | other *** search
/ Programming Languages Suite / ProgramD2.iso / Borland / Borland C++ V5.02 / SUPERPD.PAK / PADITEM.CPP < prev    next >
C/C++ Source or Header  |  1997-05-06  |  6KB  |  225 lines

  1. // This is a part of the Microsoft Foundation Classes C++ library.
  2. // Copyright (C) 1992-1995 Microsoft Corporation
  3. // All rights reserved.
  4. //
  5. // This source code is only intended as a supplement to the
  6. // Microsoft Foundation Classes Reference and related
  7. // electronic documentation provided with the library.
  8. // See these sources for detailed information regarding the
  9. // Microsoft Foundation Classes product.
  10.  
  11. #include "stdafx.h"
  12. #include "padview.h"
  13. #include "paddoc.h"
  14. #include "paditem.h"
  15. #include <limits.h>
  16. #include <winnls.h>
  17.  
  18. IMPLEMENT_DYNAMIC(CEmbeddedItem, COleServerItem)
  19.  
  20. CEmbeddedItem::CEmbeddedItem(CPadDoc* pContainerDoc)
  21.     : COleServerItem(pContainerDoc, TRUE)
  22. {
  23.     m_nBeg = 0;
  24.     m_nEnd = UINT_MAX;
  25.  
  26.     // support CF_TEXT format
  27.     GetDataSource()->DelayRenderFileData(CF_TEXT);
  28. }
  29.  
  30. BOOL CEmbeddedItem::OnRenderFileData(LPFORMATETC lpFormatEtc, CFile* pFile)
  31. {
  32.     ASSERT(lpFormatEtc != NULL);
  33.     if (lpFormatEtc->cfFormat != CF_TEXT)
  34.         return COleServerItem::OnRenderFileData(lpFormatEtc, pFile);
  35.  
  36.     BOOL bResult = FALSE;
  37.     TRY
  38.     {
  39.         // save contents of this item to the file
  40.         SaveToFile(pFile);
  41.  
  42.         // CF_TEXT has NUL termination
  43.         char chZero = '\0';
  44.         pFile->Write(&chZero, sizeof(char));
  45.  
  46.         bResult = TRUE; // success
  47.     }
  48.     END_TRY
  49.  
  50.     return bResult;
  51. }
  52.  
  53. CPadView* CEmbeddedItem::GetView() const
  54. {
  55.     CDocument* pDoc = GetDocument();
  56.     ASSERT_VALID(pDoc);
  57.     POSITION pos = pDoc->GetFirstViewPosition();
  58.     if (pos == NULL)
  59.         return NULL;
  60.  
  61.     CPadView* pView = (CPadView*)pDoc->GetNextView(pos);
  62.     ASSERT_VALID(pView);
  63.     ASSERT_KINDOF(CPadView, pView);
  64.     return pView;
  65. }
  66.  
  67. void CEmbeddedItem::SaveToFile(CFile* pFile)
  68. {
  69.     CPadView* pView = GetView();
  70.     LPCTSTR lpszText = NULL;
  71.  
  72.     TRY
  73.     {
  74.         // get access to the edit buffer
  75.         lpszText = pView->LockBuffer();
  76.  
  77.         // get range (make sure inside of text length)
  78.         UINT nEnd = pView->GetWindowTextLength();
  79.         UINT nBeg = min(m_nBeg, nEnd);
  80.         nEnd = min(m_nEnd, nEnd);
  81. #ifdef _UNICODE
  82.         // copy to temp buffer, convert, then write to file
  83.         int nLen = WideCharToMultiByte(CP_ACP, 0, lpszText+nBeg, nEnd-nBeg,
  84.             NULL, 0, NULL, NULL);
  85.         char* pszTemp = new char[nLen];
  86.         WideCharToMultiByte(CP_ACP, 0, lpszText+nBeg, nEnd-nBeg,
  87.             pszTemp, nLen, NULL, NULL);
  88.         pFile->Write(pszTemp, nLen);
  89.         delete[] pszTemp;
  90. #else
  91.         // write it out to the file
  92.         pFile->Write(lpszText+nBeg, (nEnd-nBeg) * sizeof(char));
  93. #endif
  94.     }
  95.     END_TRY
  96.  
  97.     // release access to edit buffer
  98.     if (lpszText != NULL)
  99.         pView->UnlockBuffer();
  100. }
  101.  
  102. void CEmbeddedItem::Serialize(CArchive& ar)
  103. {
  104.     if (ar.IsStoring())
  105.     {
  106.         // save just the portion this item refers to
  107.         ar.Flush();
  108.         CFile* pFile = ar.GetFile();
  109.         SaveToFile(pFile);
  110.     }
  111.     else
  112.     {
  113.         // otherwise, read in the entire file
  114.         GetDocument()->Serialize(ar);
  115.     }
  116. }
  117.  
  118. BOOL CEmbeddedItem::OnGetExtent(DVASPECT dwDrawAspect, CSize& rSize)
  119. {
  120.     if (dwDrawAspect != DVASPECT_CONTENT)
  121.         return COleServerItem::OnGetExtent(dwDrawAspect, rSize);
  122.  
  123.     // no drawing will happen if cliprect is NULL
  124.     CClientDC dc(NULL);
  125.     dc.IntersectClipRect(0, 0, 0, 0);
  126.     return OnDraw(&dc, rSize);
  127. }
  128.  
  129. BOOL CEmbeddedItem::OnDraw(CDC* pDC, CSize& rSize)
  130. {
  131.     // get view attached to the item
  132.     CPadView* pView = GetView();
  133.  
  134.     // In some situations, OLE1 servers will ask for the presentation data
  135.     //  during shutdown, even though it is not necessary (since the picture
  136.     //  has not changed).  This will happen when closing a frame window
  137.     //  for example.  By this time all the views are gone and there is no
  138.     //  way to produce the metafile data, since the actual text is
  139.     //  stored by the edit control (the view).  In this case, we simply
  140.     //  fail the call.
  141.     if (pView == NULL)
  142.         return FALSE;
  143.  
  144.     // edit controls have a border around them
  145.     CRect rectClient;
  146.     CRect margin;
  147.  
  148.     { // Calculate correct ClientRect
  149.         pView->GetClientRect(&rectClient);
  150.         rectClient.InflateRect(-1,-1);
  151.  
  152.         if (pView->GetStyle() & WS_HSCROLL)
  153.             rectClient.bottom++;
  154.         if (pView->GetStyle() & WS_VSCROLL)
  155.             rectClient.right++;
  156.     }
  157.  
  158.     { // Calculate margins
  159.         CRect rectEdit;
  160.         pView->GetEditCtrl().GetRect(&rectEdit);
  161.  
  162.         if (rectEdit.IsRectEmpty())
  163.             rectEdit.SetRect(4,4,4,4);
  164.  
  165.         int HorzMargin = rectEdit.left - rectClient.left;
  166.         int VertMargin = rectEdit.top - rectClient.top;
  167.  
  168.         margin.SetRect(HorzMargin,VertMargin,HorzMargin,VertMargin);
  169.  
  170.         if (pView->GetStyle() & WS_HSCROLL)
  171.             margin.bottom++;
  172.         if (pView->GetStyle() & WS_VSCROLL)
  173.             margin.right++;
  174.     }
  175.  
  176.     // get the font from the CEditView
  177.     CFont* pFont = pView->GetFont();
  178.     CFont* pOldFont = NULL;
  179.     if (pFont != NULL)
  180.         pOldFont = pDC->SelectObject(pFont);
  181.  
  182.     // get formatting rectangle
  183.     CRect rect(rectClient);
  184.     rect.left += margin.left;
  185.     rect.top += margin.top;
  186.     rect.right -= margin.right;
  187.     rect.bottom = INT_MAX;
  188.  
  189.     pDC->SetBkMode(TRANSPARENT);
  190.  
  191.     // first just determine the correct extents of the text
  192.     pDC->SaveDC();
  193.     pDC->IntersectClipRect(0, 0, 0, 0); // no drawing with NULL clipping
  194.     if (pView->PrintInsideRect(pDC, rect, m_nBeg, m_nEnd) == 0)
  195.     {
  196.         TEXTMETRIC tm;
  197.         pDC->GetTextMetrics(&tm);
  198.         rect.bottom = rect.top + tm.tmHeight + tm.tmExternalLeading;
  199.     }
  200.     pDC->RestoreDC(-1);
  201.  
  202.     // then, really output the text
  203.     pDC->SetWindowOrg(rect.left-margin.left,rect.top-margin.top);
  204.     pDC->SetWindowExt(margin.left + rect.Width() + margin.right,
  205.         margin.top + rect.Height() + margin.bottom);
  206.     pView->PrintInsideRect(pDC, rect, m_nBeg, m_nEnd);
  207.  
  208.     // adjust for border (rect.left is already adjusted)
  209.     rect.left -= margin.left;
  210.     rect.top -= margin.top;
  211.     rect.right += margin.right;
  212.     rect.bottom += margin.bottom;
  213.  
  214.     // select previous font
  215.     if (pOldFont != NULL)
  216.         pDC->SelectObject(pOldFont);
  217.  
  218.     // return HIMETRIC size
  219.     rSize = rect.Size();
  220.     pDC->LPtoHIMETRIC(&rSize);
  221.     return TRUE;
  222. }
  223.  
  224. /////////////////////////////////////////////////////////////////////////////
  225.